package ru.housewife.form;

import org.apache.commons.collections.Factory;
import org.apache.commons.collections.map.LazyMap;
import ru.housewife.cache.CacheManager;
import ru.housewife.model.CookingDishComponent;
import ru.housewife.model.CookingDishRecipe;

import java.util.*;

/**
 * Form object for
 * @see ru.housewife.model.CookingDishRecipe
 *
 * @author Alexander Troshanin
 */
public class CookingDishRecipeForm implements Comparable<CookingDishRecipeForm> {

    private long id;

    private String name;

    private String wayToPrepare;

    private CookingDishRecipeGroupForm group;

    private List<CookingDishComponentForm> components;

    private Map<Long, CookingDishComponentForm> componentsMap;

    private boolean singleComponent;        // indicates that this dish recipe is just a single product based, like 1kg of apples for dinner.

    private boolean commonRecipe;        // indicates that this dish recipe is common and used by many users, so it could not be modified.

    private Map<Long, CookingDishComponentForm> uiComponents;

    private long ownerId;

    public CookingDishRecipeForm() {
        uiComponents = LazyMap.decorate(new TreeMap<Long, CookingDishComponentForm>(), new Factory() {
            @Override
            public CookingDishComponentForm create() {
                return new CookingDishComponentForm();
            }
        });
        group = CacheManager.getInstance().getDefaultRecipesGroup();
    }

    public CookingDishRecipeForm(CookingDishRecipeForm recipe) {
        this();
        this.id = recipe.id;
        this.name = recipe.name;
        this.wayToPrepare = recipe.wayToPrepare;
        this.commonRecipe = recipe.commonRecipe;
        this.group = recipe.group;
        for (CookingDishComponentForm component : recipe.getComponents()) {
            uiComponents.put(component.getId(), component);
        }
        this.ownerId = recipe.ownerId;
    }

    public Map<Long, CookingDishComponentForm> getUiComponents() {
        return uiComponents;
    }

    public Set<Long> getUiComponentsKeys() {
        return uiComponents.keySet();
    }

    public Set<Map.Entry<Long, CookingDishComponentForm>> getUiComponentsEntries() {
        return uiComponents.entrySet();
    }

    public CookingDishRecipeForm(CookingDishRecipe recipe) {
        init(recipe);
    }

    public void init(CookingDishRecipe recipe) {
        id = recipe.getId();
        commonRecipe = recipe.isCommonRecipe();
        name = recipe.getName();
        singleComponent = recipe.isSingleComponent();
        wayToPrepare = recipe.getWayToPrepare();
        group = CacheManager.getInstance().getCookingDishRecipeGroupForm(recipe.getRecipesGroup().getId());

        components = new ArrayList<CookingDishComponentForm>(recipe.getComponents().size());
        componentsMap = new HashMap<Long, CookingDishComponentForm>();
        for (CookingDishComponent component : recipe.getComponents()) {
            IngredientForm ingredientForm = CacheManager.getInstance().getIngredientForm(component.getIngredient().getId());
            if (ingredientForm == null) {
                // TODO: add LOG warning here
                continue;
            }
            WareForm wareForm = null;
            if (component.getPreferableWare() != null) {
                wareForm = CacheManager.getInstance().getWareForm(component.getPreferableWare().getId());
            }
            CookingDishComponentForm componentForm = new CookingDishComponentForm(component, ingredientForm, wareForm);
            componentForm.setRecipe(this);
            components.add(componentForm);
            componentsMap.put(componentForm.getId(), componentForm);
        }
        ownerId = recipe.getOwner().getId();
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getWayToPrepare() {
        return wayToPrepare;
    }

    public void setWayToPrepare(String wayToPrepare) {
        this.wayToPrepare = wayToPrepare;
    }

    public CookingDishRecipeGroupForm getGroup() {
        return group;
    }

    public void setGroup(CookingDishRecipeGroupForm group) {
        this.group = group;
    }

    public CookingDishComponentForm getComponent(long componentId) {
        return componentsMap.get(componentId);
    }

    public List<CookingDishComponentForm> getComponents() {
        return components;
    }

    public void setComponents(List<CookingDishComponentForm> components) {
        this.components = components;
    }

    public boolean isSingleComponent() {
        return singleComponent;
    }

    public void setSingleComponent(boolean singleComponent) {
        this.singleComponent = singleComponent;
    }

    public boolean isCommonRecipe() {
        return commonRecipe;
    }

    public void setCommonRecipe(boolean commonRecipe) {
        this.commonRecipe = commonRecipe;
    }

    public long getOwnerId() {
        return ownerId;
    }

    public void setOwnerId(long ownerId) {
        this.ownerId = ownerId;
    }

    @Override
    public int compareTo(CookingDishRecipeForm that) {
        if (that == null || that.name == null) {
            return -1;
        }
        return this.name.compareTo(that.name);
    }
}
